package justbuy.payment.service.alipay;

import java.util.HashMap;
import java.util.Map;

import javax.inject.Named;
import javax.inject.Singleton;

import justbuy.payment.service.AbstractPaymentService;
import justbuy.payment.service.Trade;

import org.ironrhino.core.util.HttpClientUtils;
import org.ironrhino.core.util.XmlUtils;
import org.springframework.beans.factory.annotation.Value;

@Named
@Singleton
public class Alipay extends AbstractPaymentService {

	@Value("${alipay.logo:http://img.alipay.com/home/logo.png}")
	private String logo;

	public String getLogo() {
		return logo;
	}

	public String getPartner() {
		return settingControl.getStringValue("payment." + getName()
				+ ".partner");
	}

	public String getKey() {
		return settingControl.getStringValue("payment." + getName() + ".key");
	}

	@Override
	public String generateHtmlForm(String orderCode, String baseURL,
			Map<String, String> params) {
		Trade trade = tradeHandler.findByCode(orderCode);
		if (trade == null)
			return "";
		if (!getName().equals(trade.getPaymentService())) {
			trade.setPaymentService(getName());
			tradeHandler.update(trade);
		}
		params.put("_input_charset", AlipayHelper.ENCODING);
		params.put("return_url", baseURL + "/payment/gateway/ret/" + getName());
		params.put("notify_url", baseURL + "/payment/gateway/ntf/" + getName());
		params.put("partner", getPartner());
		params.put("out_trade_no", trade.getCode());
		params.put("subject", trade.getTitle());
		if (!params.containsKey("price"))
			params.put("total_fee", trade.getGrandTotal().toString());
		if (params.get("service") == null)
			params.put("service", "create_direct_pay_by_user");
		if (params.get("payment_type") == null)
			params.put("payment_type", "1");
		if (params.get("service").equals("create_partner_trade_by_buyer")) {
			params.put("seller_id", getPartner());
			params.put("price", trade.getGrandTotal().toString());
			params.put("quantity", "1");
			params.put("payment_type", "1");
			params.put("logistics_type", "EXPRESS");
			params.put("logistics_fee", "0");
			params.put("logistics_payment", "SELLER_PAY");
		}
		AlipayHelper.addSign(params, getKey());
		StringBuilder sb = new StringBuilder();
		sb.append("<form id=\"payment_form\" action=\"" + AlipayHelper.GATEWAY
				+ "?_input_charset=" + AlipayHelper.ENCODING
				+ "\" method=\"post\" target=\"_blank\">");
		for (Map.Entry<String, String> entry : params.entrySet()) {
			String name = entry.getKey();
			String value = entry.getValue();
			if (name.equals("_input_charset"))
				continue;
			sb.append("<input type=\"hidden\" name=\"" + name + "\" value=\""
					+ value + "\"/>");
		}
		sb.append("<input type=\"submit\" value=\"支付宝确认付款\"/></form>");
		return sb.toString();
	}

	@Override
	public void handleReturn(Map<String, String> params) {
		params = AlipayHelper.getVerifiedParams(params, getPartner(), getKey());
		String orderCode = params.get("out_trade_no");
		Trade trade = tradeHandler.findByCode(orderCode);
		trade.setPaymentService(getName());
		trade.setPaymentService(params.get("trade_no"));
		trade.setPaid("T".equals(params.get("is_success")));
		tradeHandler.update(trade);
		tradeHandler.preReturn(trade);
	}

	@Override
	public String handleNotify(Map<String, String> params) {
		params = AlipayHelper.getVerifiedParams(params, getPartner(), getKey());
		if (params == null)
			return null;
		String orderCode = params.get("out_trade_no");
		Trade trade = tradeHandler.findByCode(orderCode);
		if (trade == null)
			return null;
		trade.setTradeNo(params.get("trade_no"));
		trade.setPaymentService(getName());
		trade.setPaid("TRADE_SUCCESS".equals(params.get("trade_status")));
		trade.setRefunded("REFUND_SUCCESS".equals(params.get("refund_status")));
		tradeHandler.update(trade);
		return tradeHandler.postNotify(trade);
	}

	@Override
	public void ship(String orderCode, String baseURL) {
		Trade trade = tradeHandler.findByCode(orderCode);
		if (trade == null)
			return;
		StringBuilder sb = new StringBuilder(AlipayHelper.GATEWAY);
		Map<String, String> params = new HashMap<String, String>();
		params.put("_input_charset", AlipayHelper.ENCODING);
		params.put("service", "send_goods_confirm_by_platform");
		params.put("return_url", baseURL + "/payment/gateway/ret/" + getName());
		params.put("notify_url", baseURL + "/payment/gateway/ntf/" + getName());
		params.put("partner", getPartner());
		params.put("trade_no", trade.getTradeNo());
		params.put("logistics_name", trade.getLogistics().getProvider());
		params.put("invoice_no", trade.getLogistics().getInvoiceNo());
		params.put("transport_type", trade.getLogistics().getType());
		AlipayHelper.addSign(params, getKey());
		String content = HttpClientUtils.getResponseText(sb.toString(), params);
		String trade_status = XmlUtils.eval(
				"/alipay/response/tradeBase/trade_status", content);
		trade.setShipped("WAIT_BUYER_CONFIRM_GOODS".equals(trade_status));
		tradeHandler.update(trade);
	}

	public void refund(String orderCode, String baseURL) {
		throw new RuntimeException("not supported by alipay");
	}

}
